﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Data;
using System.Data.SqlClient;
using DM4;
using DM4.InfoClasses;
using sscore;

namespace DMN_Log
{
    public class DMN_Log : DaemonBase, IDisposable   
    {
        private static readonly object LogLocker = new object();
        
        private readonly string _insertSQLplusSessId = "INSERT INTO {0} ([lg_time],[lg_mess_type],[lg_mod_code],[lg_sess_id],[lg_usr_id],[lg_message]) VALUES (@lg_time,@lg_mess_type,@lg_mod_code,@lg_sess_id,@lg_usr_id,@lg_message)";
        private readonly string _insertSQL = "INSERT INTO {0} ([lg_time],[lg_mess_type],[lg_mod_code],[lg_usr_id],[lg_message]) VALUES (@lg_time,@lg_mess_type,@lg_mod_code,@lg_usr_id,@lg_message)";
        //private SqlCommand insert_Log_Error = null;
        //private SqlCommand insert_Log_General = null;
        //private SqlCommand insert_Log_System = null;
        //private SqlCommand insert_Log_Test = null;
        //private SqlCommand insert_Log_Daemons = null;

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
        }

        ~DMN_Log()
        {
            Dispose(false);
        }

        public DMN_Log()
        {
            ModuleCode = "DMN_Log";
            Description = "Log module";
            Debug = false;
        }

        public override OperationResult Init(IDM4Core iCore, DmTaskParams param = null)
        {
            base.Init(iCore, param);

            WriteLog(String.Format("Initialize daemon [{0}]...", ModuleCode));
            WriteLog(String.Format("Initialize daemon [{0}] complete", ModuleCode));

            WriteLog("Initialize module, create worker instance");
            
            return new OperationResult { Result = DM4Consts.Ok };
        }

        public override OperationResult Start()
        {
            OperationResult or = new OperationResult { Result = DM4Consts.Ok, Message = "" };
            WriteLog(String.Format("Start daemon [{0}] ...", ModuleCode));
            base.Start();

            Status = DaemonStatus.Starting;

            try
            {                
                //insert_Log_Error = new SqlCommand(String.Format(_insertSQLplusSessId, "[log_error]"), _connection);
                //insert_Log_Error.Parameters.Add("@lg_time", SqlDbType.DateTime);
                //insert_Log_Error.Parameters.Add("@lg_mess_type", SqlDbType.Int);
                //insert_Log_Error.Parameters.Add("@lg_mod_code", SqlDbType.NVarChar, -1);
                //insert_Log_Error.Parameters.Add("@lg_sess_id", SqlDbType.NVarChar, -1);
                //insert_Log_Error.Parameters.Add("@lg_usr_id", SqlDbType.Int);
                //insert_Log_Error.Parameters.Add("@lg_message", SqlDbType.NVarChar, -1);
                //insert_Log_Error.Prepare();

                //insert_Log_General = new SqlCommand(String.Format(_insertSQLplusSessId, "[log_general]"), _connection);
                //insert_Log_General.Parameters.Add("@lg_time", SqlDbType.DateTime);
                //insert_Log_General.Parameters.Add("@lg_mess_type", SqlDbType.Int);
                //insert_Log_General.Parameters.Add("@lg_mod_code", SqlDbType.NVarChar, -1);
                //insert_Log_General.Parameters.Add("@lg_sess_id", SqlDbType.NVarChar, -1);
                //insert_Log_General.Parameters.Add("@lg_usr_id", SqlDbType.Int);
                //insert_Log_General.Parameters.Add("@lg_message", SqlDbType.NVarChar, -1);
                //insert_Log_General.Prepare();

                //insert_Log_System = new SqlCommand(String.Format(_insertSQL, "[log_system]"), _connection);
                //insert_Log_System.Parameters.Add("@lg_time", SqlDbType.DateTime);
                //insert_Log_System.Parameters.Add("@lg_mess_type", SqlDbType.Int);
                //insert_Log_System.Parameters.Add("@lg_mod_code", SqlDbType.NVarChar, -1);
                //insert_Log_System.Parameters.Add("@lg_usr_id", SqlDbType.Int);
                //insert_Log_System.Parameters.Add("@lg_message", SqlDbType.NVarChar, -1);
                //insert_Log_System.Prepare();

                //insert_Log_Test = new SqlCommand(String.Format(_insertSQLplusSessId, "[log_test]"), _connection);
                //insert_Log_Test.Parameters.Add("@lg_time", SqlDbType.DateTime);
                //insert_Log_Test.Parameters.Add("@lg_mess_type", SqlDbType.Int);
                //insert_Log_Test.Parameters.Add("@lg_mod_code", SqlDbType.NVarChar, -1);
                //insert_Log_Test.Parameters.Add("@lg_sess_id", SqlDbType.NVarChar, -1);
                //insert_Log_Test.Parameters.Add("@lg_usr_id", SqlDbType.Int);
                //insert_Log_Test.Parameters.Add("@lg_message", SqlDbType.NVarChar, -1);
                //insert_Log_Test.Prepare();

                //insert_Log_Daemons = new SqlCommand(String.Format(_insertSQL, "[log_daemons]"), _connection);
                //insert_Log_Daemons.Parameters.Add("@lg_time", SqlDbType.DateTime);
                //insert_Log_Daemons.Parameters.Add("@lg_mess_type", SqlDbType.Int);
                //insert_Log_Daemons.Parameters.Add("@lg_mod_code", SqlDbType.NVarChar, -1);
                //insert_Log_Daemons.Parameters.Add("@lg_usr_id", SqlDbType.Int);
                //insert_Log_Daemons.Parameters.Add("@lg_message", SqlDbType.NVarChar, -1);
                //insert_Log_Daemons.Prepare();

                Status = DaemonStatus.Run;
            }
            catch (Exception ex)
            {
                WriteLog(String.Format("Error occurred while start [{0}] module. {1}{2}{1}{3}", ModuleCode, Environment.NewLine, ex.Message, ex.StackTrace), MessageType.Error);
                or.Result = DM4Consts.ErrorUnknown;
                or.Message = ex.Message;
                Status = DaemonStatus.Stop;
            }

            return or;
        }

        public override OperationResult Execute(string cmdName, object commandParameters)
        {
            OperationResult or = new OperationResult { Result = DM4Consts.Ok, Message = "" };

            if (cmdName.ToUpper() == LogCommands.InsertLog.ToUpper()) //вставка лога
            {
                if (commandParameters is LogParameters)
                {
                    try
                    {
                        SqlCommand command = null;
                        LogParameters param = (LogParameters)commandParameters;

                        //switch (param.logType)
                        //{
                        //    case LogType.Error: command = insert_Log_Error; break;
                        //    case LogType.General: command = insert_Log_General; break;
                        //    case LogType.System: command = insert_Log_System; break;
                        //    case LogType.Test: command = insert_Log_Test; break;
                        //    case LogType.Daemons: command = insert_Log_Daemons; break;
                        //}

                        switch (param.logType)
                        {
                            case LogType.Error:
                                command = new SqlCommand(String.Format(_insertSQLplusSessId, "[log_error]"), Core.GetDBConnection());
                                break;
                            case LogType.General:
                                command = new SqlCommand(String.Format(_insertSQLplusSessId, "[log_general]"), Core.GetDBConnection());
                                break;
                            case LogType.System:
                                command = new SqlCommand(String.Format(_insertSQL, "[log_system]"), Core.GetDBConnection());
                                break;
                            case LogType.Test:
                                command = new SqlCommand(String.Format(_insertSQLplusSessId, "[log_test]"), Core.GetDBConnection());
                                break;
                            case LogType.Daemons:
                                command = new SqlCommand(String.Format(_insertSQL, "[log_daemons]"), Core.GetDBConnection());
                                break;
                         }

                        command.Parameters.AddWithValue("@lg_time", DateTime.Now);
                        command.Parameters.AddWithValue("@lg_mess_type", param.messType);
                        command.Parameters.AddWithValue("@lg_mod_code", param.modCode);
                        command.Parameters.AddWithValue("@lg_usr_id", param.usrId);
                        command.Parameters.AddWithValue("@lg_message", param.message);

                        switch (param.logType)
                        {
                            case LogType.Error:
                            case LogType.General:
                            case LogType.Test:
                                command.Parameters.AddWithValue("@lg_sess_id", param.sessId);
                                break;
                        }

                        command.ExecuteNonQuery();
                    }
                    catch (Exception ex)
                    {
                        WriteLog(String.Format("Error occurred while Execute [{0}] module. {1}{2}{1}{3}", ModuleCode, Environment.NewLine, ex.Message, ex.StackTrace), MessageType.Error);
                        //Status = DaemonStatus.Stop;
                    }
                }
                else
                {
                    or.Result = DM4Consts.ErrorUnknownEntity;
                    or.Message = "Invalid parameters type, must be passed LogParameters class instance.";
                }
            }
            else
            {
                or.Result = DM4Consts.ErrorUnknownCommand;
                or.Message = "Invalid command name for DNM_Log .";
            }
            
            return or;
        }

        public override OperationResult Stop()
        {
            WriteLog(String.Format("Stop daemon [{0}] ...", ModuleCode));
            Status = DaemonStatus.Stopping;
            
            Status = DaemonStatus.Stop;

            return new OperationResult { Result = DM4Consts.Ok, Message = "" };
        }
    }
}
